from pml import Objects
from pml import PML

class PMIntegerObject(Objects.object.typeobject):
    def __init__(self, value: int = 0):
        super().__init__('integer')
        self.value = value
        self.iter = -1
    def __repr__(self):
        return self.value.__repr__()
    def __str__(self):
        return self.value.__str__()
    def __hash__(self):
        return self.value.__hash__()

    def __iter__(self):
        self.iter = -1
        return self
    def __next__(self):
        self.iter += 1
        if self.iter == self.value:
            raise StopIteration
        return PML.object.ChangeObject.PMLInteger_FromInt(self.iter + 1)
    def __reduce__(self):
        return PMIntegerObject, (self.value, )

    def getObject(self):
        self.methods['__init__'] = self.tp_init
        self.methods['__print__'] = self.tp_print

        self.methods['__string__'] = self.tp_string
        self.methods['__boolean__'] = self.tp_boolean

        self.methods['__addition__'] = self.tp_addition
        self.methods['__subtraction__'] = self.tp_subtraction
        self.methods['__multiplication__'] = self.tp_multiplication
        self.methods['__division__'] = self.tp_division

        self.methods['__left_positive__'] = self.tp_left_positive
        self.methods['__left_negative__'] = self.tp_left_negative

        return self

    @staticmethod
    def tp_init(frame, this, position, value):
        pass

    @staticmethod
    def tp_print(frame, this, position):
        return this.tp_string(frame, this, position=position)


    @staticmethod
    def tp_string(frame, this, position):
        return Objects.object.PMTypeObject(Objects.PMStringObject.PMStringObject(str(this.value)).getObject())
    @staticmethod
    def tp_boolean(frame, this, position):
        return Objects.object.PMTypeObject(Objects.PMBooleanObject.PMBooleanObject(this.value > 0).getObject())


    @staticmethod
    def tp_addition(frame, this, position, other):
        if PML.object.PMLTypeEquality(other, Objects.PMStringObject.PMStringObject):
            return Objects.object.PMTypeObject(Objects.PMStringObject.PMStringObject(this.value.__str__() + other.obj.value).getObject())
        else:
            return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(this.value + other.obj.value).getObject())
    @staticmethod
    def tp_subtraction(frame, this, position, other):
        return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(this.value - other.obj.value).getObject())
    @staticmethod
    def tp_multiplication(frame, this, position, other):
        return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(this.value * other.obj.value).getObject())
    @staticmethod
    def tp_division(frame, this, position, other):
        return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(this.value / other.obj.value).getObject())

    @staticmethod
    def tp_left_positive(frame, this, position):
        return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(this.value).getObject())

    @staticmethod
    def tp_left_negative(frame, this, position):
        return Objects.object.PMTypeObject(Objects.PMIntegerObject.PMIntegerObject(-this.value).getObject())
